package com.zzq.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
import com.zzq.config.wx.*;
import com.zzq.domain.bo.SmileFeeBO;
import com.zzq.domain.dto.SmileShootAddressDTO;
import com.zzq.domain.dto.SmileShootRecordDTO;
import com.zzq.domain.entity.*;
import com.zzq.domain.search.ShootRecordSearchParament;
import com.zzq.result.SmileResult;
import com.zzq.security.util.UserUtil;
import com.zzq.service.*;
import com.zzq.subservice.CostcalculcationSubService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.List;

@Service
public class ClientWxPayServiceImpl  implements ClientWxPayService {
    @Autowired
    SmileAlbumService albumService;
    @Autowired
    SmileAlbumPhotoService albumPhotoService;

    @Autowired
    SmileShootAddressService shootAddressService;
    @Autowired
    SmileShootRecordService recordService;
    @Value("${wx.pay.jsapiurl}")
    private String jsapiurl;

    @Autowired
    private WxJsapiConfig wxJsapiConfig;

    @Autowired
    private WxPayConfigLoader wxPayConfigLoader;

    @Autowired
    private SignV3Utils signV3Utils;

    @Autowired
    private CostcalculcationSubService costcalculcationUtil;

    @Override
    @Transactional
    public SmileResult generateRecord(ShootRecordSearchParament photoSearchParamet) throws Exception {
        SmileFeeBO amountSmileFeeDTO = costcalculcationUtil.getAmountSmileFeeDTO(photoSearchParamet);
        BigDecimal amount = amountSmileFeeDTO.getAmount();


        //生成订单
        SmileShootRecord record=new SmileShootRecord();
        Long clientId = UserUtil.getUserID();
        record.setClientId(clientId);
        record.setClientNo(photoSearchParamet.getClientNo());
        record.setAlbumId(photoSearchParamet.getAlbumId());
        record.setChooseNum(photoSearchParamet.getPhotoIds().size());
        record.setShootAddressId(photoSearchParamet.getShootAddressId());
        record.setAmount(amount);
        record.setFeeId(amountSmileFeeDTO.getId());

        if (photoSearchParamet.getFavorable()){
            //优惠金额
            BigDecimal favorableAmount = amountSmileFeeDTO.getFavorableAmount();
            record.setUnfavorableAmount(amount.add(favorableAmount));
            record.setFavorable(true);
        }else {
            record.setFavorable(false);
            record.setUnfavorableAmount(amount);
        }
        recordService.save(record);



        Long recordId = record.getId();

        List<Long> photoIds = photoSearchParamet.getPhotoIds();
        for (Long photoId : photoIds) {
            LambdaUpdateWrapper<SmileAlbumPhoto> updateWrapper=new LambdaUpdateWrapper<>();
            updateWrapper.eq(SmileAlbumPhoto::getAlbumId,photoSearchParamet.getAlbumId());
            updateWrapper.eq(SmileAlbumPhoto::getPhotoId,photoId);
            updateWrapper.set(SmileAlbumPhoto::getShootRecordId,recordId);

            albumPhotoService.update(updateWrapper);
        }

        /*
        needPay 当需要付钱的金额为0元的时候只生成订单，无需去微信生成订单
         */

        if (record.getAmount().compareTo(new BigDecimal(0))==0){
            HashMap map=new HashMap();
            map.put("needPay",false);
            map.put("shootRecordId",record.getId());
            return SmileResult.sucess("成功",map);
        }



        String prepayId = "prepay_id=" +sendWxServerOrder(record);
        String sign = signV3Utils.getSign(wxJsapiConfig.getAppid(), photoSearchParamet.getTimestamp(), photoSearchParamet.getNonceStr(),  prepayId);
        HashMap map=new HashMap();
        map.put("needPay",true);
        map.put("package",prepayId);
        map.put("paySign",sign);
        map.put("shootRecordId",record.getId());
        return SmileResult.sucess("成功",map);
    }

    @Override
    public SmileResult recordList()  {
        String clientNo = UserUtil.getUser().getClientNo();
        ShootRecordSearchParament shootRecordSearchParament = new ShootRecordSearchParament();
        shootRecordSearchParament.setClientNo(clientNo);
        List<SmileShootRecordDTO> smileShootRecordDTOs = recordService.getSmileShootRecordDTOs(shootRecordSearchParament);
        return SmileResult.sucess(smileShootRecordDTOs);
    }


    public String  sendWxServerOrder(SmileShootRecord record) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {

        record.setRecordOrderNo("SP-"+record.getId());
        Long albumId = record.getAlbumId();
        SmileShootAddressDTO shootAddress = shootAddressService.getShootAddressDTObyId(record.getShootAddressId());
        SmileClient client = UserUtil.getUser();
        String openId = client.getOpenId();
        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(wxJsapiConfig.getMchid())
                        .privateKey(wxPayConfigLoader.loadPrivateKey(wxJsapiConfig.getPrivatekey()))
                        .merchantSerialNumber(wxJsapiConfig.getSerialno())
                        .apiV3Key(wxJsapiConfig.getApiV3Key())
                        .build();
        // 构建service
        JsapiService service = new JsapiService.Builder().config(config).build();
        // request.setXxx(val)设置所需参数，具体参数可见Request定义
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(record.getAmount().multiply(BigDecimal.valueOf(100)).intValue());
        amount.setCurrency("CNY");
        request.setAmount(amount);
        request.setAppid(wxJsapiConfig.getAppid());
        request.setMchid(wxJsapiConfig.getMchid());
                               // 地点名称 ， x张
        request.setDescription(shootAddress.getShootName()+","+record.getChooseNum()+"张");
        request.setNotifyUrl(wxJsapiConfig.getNotify_url());
        request.setOutTradeNo(record.getRecordOrderNo());
        Payer payer = new Payer();
        payer.setOpenid(openId);
        request.setPayer(payer);

        // 调用下单方法，得到应答
        PrepayResponse response = service.prepay(request);
        return response.getPrepayId();

    }




}
